<template>
  <view
    class="hoverBallBox"
    :style="{
      width: `${boxWidth}px`,
      height: `${boxHeight}px`,
      top: `${top}px`,
      left: `${left}px`,
    }"
    @touchmove.stop.prevent="touchmove"
    @touchend="touchend"
    @touchcancel="touchcancel"
    :animation="ballAnimation"
  >
    <slot></slot>
  </view>
</template>

<script lang="ts" setup>
  import { ref, unref } from 'vue';

  const props = defineProps({
    headerHeight: {
      type: Number,
      default: 44
    },
    boxWidth: {
      type: Number,
      default: 50
    },
    boxHeight: {
      type: Number,
      default: 50
    }
  });

  const top = ref(0);
  const left = ref(0);
  const paddingX = ref(20); // 左右边距
  const paddingY = ref(10); // 上下边距
  const isMove = ref(false);
  const ballAnimation = ref<any>();
  const timeout = ref<any>();

  const { safeArea } = uni.getWindowInfo()
  if(safeArea){
    top.value = safeArea.height - unref(props.boxHeight) - unref(paddingY); // 初始位置
    left.value = safeArea.width - unref(props.boxWidth) - unref(paddingX); // 初始位置
  }


  function touchmove(e:any) {
    isMove.value = true;
    if (timeout.value != null) {
      clearTimeout(timeout.value);
      timeout.value = null;
    }
    let touch = e.touches[0] || e.changedTouches[0];
    left.value = touch.clientX;
    top.value = touch.clientY;
  };

  function touchend(e:any) {
    if (!unref(isMove)) {
      return;
    }
    finish(e);
  };
  function touchcancel(e:any) {
    if (!unref(isMove)) {
      return;
    }
    finish(e);
  };
  function finish(e:any) {
      isMove.value = false;
      let touch = e.touches[0] || e.changedTouches[0];
      left.value = touch.clientX;
      top.value = touch.clientY;
      if(!safeArea) return
      if (2 * left.value + props.boxWidth >= safeArea.width) {
        // 右侧滑动出屏幕外,归位
        left.value = safeArea.width - props.boxWidth - paddingX.value;
      } else {
        // 左侧滑动出屏幕外,归位
        left.value = paddingX.value;
      }
      if (top.value > safeArea.height - props.boxHeight - paddingY.value) {
        // 底部划出最大高度,归位
        top.value = safeArea.height - props.boxHeight - paddingY.value;
      } else if (top.value < props.headerHeight + paddingY.value) {
        // 顶部划出最小高度,归位
        top.value = props.headerHeight + paddingY.value
      }
      let create = uni.createAnimation({
        duration: 0,
      });
      create.translate(0, 0).step();
      ballAnimation.value = create.export();
    };
</script>

<style lang="scss" scoped>
.hoverBallBox {
  position: fixed;
  z-index: 98;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background-color: #FFFFFF;
  border-radius: 20rpx;
  box-shadow: 0px 0px 4px 0px rgba(0,0,0,0.15);
}
</style>
